home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ddj9304.zip / 1993-APR.ZIP / WAVELET.ASC < prev   
Text File  |  1993-02-17  |  33KB  |  774 lines

  1. _A WAVELET ANALYZER_
  2. by Mac A. Cody
  3.  
  4. [LISTING ONE]
  5.  
  6. #include "dsp_type.h"
  7. #if DSP32
  8. #include "dspregs.h"
  9. #endif
  10.  
  11. .global DECOMP
  12.         /*  DECOMP
  13.             perform recursive decomposition on non-terminating data sequence
  14.             registers used: r1 r2 r3 r4 r5 r6 r11 r12 r13 r14 r15 r16
  15.             accumulators used: a0 a1
  16.             input: r1 - pointer to wavelet high-pass filter coefficients
  17.                    r2 - pointer to wavelet low-pass filter coefficients
  18.                    r6 - pointer to wavelet output data list
  19.                    r11 - jump address for proper filter length
  20.                    r12 - pointer to data pointer array
  21.                    r13 - pointer to stack
  22.                    r14 - return stack register, i.e. "TOP OF STACK"
  23.                    r15 - recursion counter
  24.                    r16 - filter coefficient pointer wrap back index
  25.         */
  26. DECOMP:   r3e = *r12++; /* load pointer to approx. input array source */
  27.           r5e = *r12;   /* load pointer to approx. output array destination */
  28.           goto r11;     /* jump to appropriate filter processing for length */
  29.           r4e = r3 + 8; /* set pointer to approx. input array destination */
  30. DT6:      a0 = a0 + *r3++ * *r1++; /* pass data through high-pass wavelet */
  31.           a0 = a0 + *r3++ * *r1++; /* filter (a0 = 0.0 initially) */
  32. DT4:      a0 = a0 + *r3++ * *r1++; /* the destination of the jump depends */
  33.           a0 = a0 + *r3++ * *r1++; /* upon the length of the wavelet */
  34. DT2:      a0 = a0 + *r3++ * *r1++; /* filter */
  35.           goto r11 + 28; /* jump to appropriate filter processing for length */
  36.           *r6++ = a0 = a0 + *r3++r16 * *r1++r16; /* output is detail point */
  37. AT6:      a1 = a1 + (*r4++ = *r3++) * *r2++; /* pass data through low-pass */
  38.           a1 = a1 + (*r4++ = *r3++) * *r2++; /* filter (a1 = 0.0 initially) */
  39. AT4:      a1 = a1 + (*r4++ = *r3++) * *r2++;
  40.           a1 = a1 + (*r4++ = *r3++) * *r2++;
  41. AT2:      a1 = a1 + *r3++ * *r2++;
  42.           a1 = a1 + *r3++ * *r2++r16;
  43.           r15 = r15 - 1;         /* check the recursion count */
  44.           if (eq) goto NO_RECUR; /* if true, recursion at bottom of tree */
  45.           r5e & 0x0004;          /* check for even/odd status */
  46.           *r5-- = a1 = a1;       /* save approx. data for next level */
  47.           if (ne) goto CLEAN_UP; /* if true, await another data point */
  48.           r4e = r5 + 8;          /* wrap output pointer back */
  49.           *r12++ = r4e;          /* save wrapped pointer to approx. O/P */
  50.           *r13-- = r14e;         /* save return address to stack */
  51.           a0 = a0 - a0;          /* clear the accumulators */
  52.           call DECOMP (r14);     /* recurse down the tree */
  53.           a1 = a0;
  54. #if DSP32C
  55.           r13e = r13 + 4;        /* align stack pointer to return address */
  56. #else
  57.           r13 = r13 + 2;         /* align stack pointer to return address */
  58. #endif
  59.           r14e = *r13;           /* pop the return address */
  60.           nop;
  61.           return (r14);
  62.           nop;
  63.  
  64. NO_RECUR: *r6 = a1 = a1;         /* save approx. coeff. as next value */
  65. CLEAN_UP: return (r14);
  66.           *r12++ = r5e;          /* save unwrapped pointer to approx. output */
  67.         /* END OF DECOMP */
  68.  
  69.  
  70. [LISTING TWO]
  71.  
  72. #include "dsp_type.h"
  73. #if DSP32
  74. #include "dspregs.h"
  75. #endif
  76.  
  77. .global DRAWIMAG
  78.      /*  DRAWIMAG -- draw image of supplied point and connect to previous point
  79.             registers used: r1 r2 r3 r4 r5 r6 r7 r12 r13 r14
  80.             accumulators used: a0 a1
  81.             input: r12 - pointer to data pointer array
  82.                    r13 - pointer to stack
  83.                    r14 - return stack register, i.e. "TOP OF STACK"
  84.                    a0 - data point to draw
  85.     */
  86. DRAWIMAG: a0 = *r12++ - a0 * *r12++; /* multiply by scalling coefficient */
  87.           a1 = -a0 + *r12;    /* determine if value above upper threshold */
  88.           a0 = ifalt(*r12++); /* if true, limit data to threshold */
  89.           a1 = a0 - *r12;     /* determine if value below lower threshold */
  90.           a0 = ifalt(*r12++); /* if true, limit data to threshold */
  91.           *r12++ = a0 = int(a0); /* convert data to integer format */
  92.           nop;
  93.           r6e = r12 - 2;        /* point to temporary storage */
  94.           r1 = *r12++;          /* load the row increment value */
  95.           r4 = *r12++;          /* load the row baseline offset value */
  96.           r2 = *r12++;          /* load the bit pointer */
  97.           r3e = *r12;           /* load the byte column pointer */
  98.           r6 = *r6;             /* read the new byte column pointer offset */
  99.           r2 - 0x80;            /* check if first bit of new byte column */
  100.           if (ne) goto ADD_BAR; /* if true, add new bar to byte column */
  101.           nop;
  102. #if DSP32C
  103.           r6 - 23;               /* check if datum point is above baseline */
  104.           if (le) goto ABOVE_BL; /* if true, it is above the baseline */
  105.           nop;
  106.           r4 = 25;       /* top counter for clearing of pixel over bar */
  107.           r5 = r6 - 24;  /* middle counter for draw of bar pixels */
  108.           goto DRAW_COL; /* go draw the column of pixels */
  109.           r6 = 48 - r6;  /* bottom counter for clearing of pixel under bar */
  110.  
  111. ABOVE_BL: r4 = r6;      /* top counter for clearing of pixel over bar */
  112.           r5 = r6;
  113.           r5 = 24 - r5; /* middle counter for draw of bar pixels */
  114.           r6 = 25;      /* bottom counter for clearing of pixel under bar */
  115. DRAW_COL: r4 = r4 - 1;  /* check if no top pixels are to be cleared */
  116.           if (lt) goto NO_TOP; /* if true, skip clearing bytes above bar */
  117.           r7 = r7 - r7;        /* force the register to zero */
  118.           do 0, r4;            /* repeat next instruntion r4+1 times */
  119.           *r3++r1 = r7l;       /* zero the bytes above the bar */
  120. NO_TOP:   r5 = r5 - 1;         /* check if no bar pixels are to be set */
  121.           if (lt) goto NO_MID; /* if true, skip setting bytes of bar */
  122.           nop;
  123.           do 0, r5;         /* repeat next instruntion r5+1 times */
  124.           *r3++r1 = r2l;    /* MSB of byte is bar, others cleared */
  125. NO_MID:   r6 = r6 - 1;      /* check if no bottom pixels are to be cleared */
  126.           if (lt) goto NO_BOT; /* if true, skip clearing bytes below bar */
  127.           nop;
  128.           do 0, r6;            /* repeat next instruntion r6+1 times */
  129.           *r3++r1 = r7l;       /* zero the bytes below the bar */
  130. NO_BOT:   goto SHIFTBIT; /* go shift the bit pointer and clear up */
  131.           r3e = *r12;    /* reload the byte pointer */
  132.  
  133. ADD_BAR:  r6 - 24;              /* check if datum below baseline */
  134.           if (gt) goto BELOW_BL; /* if true, datum is below baseline */
  135.           r6 = r6 - 24;  /* calculate length of bar */
  136.           r6 = -r6;      /* datum above baseline length was negative */
  137.           r1e = -r1;     /* datum above baseline, increment is decrement */
  138. BELOW_BL: r4e = r4 + r3; /* add baseline offset to byte column pointer */
  139.           r5e = r4 + r1; /* move pointer away from the baseline */
  140.           r7 = 0;        /* zero initial storage value */
  141.           do 2, r6;      /* repeat the next 3 instructions r6+1 times */
  142.           r6l = *r5++r1; /* load the byte */
  143.           *r4++r1 = r7l; /* store the byte and move the pointer */
  144.           r7 = r6 | r2;  /* OR byte with bit pointer to set the bit */
  145. #else
  146.           r6 = r6 * 2;     /* multiply offset by four to account for ... */
  147.           r6 = r6 * 2;     /* four bytes per instruction in MEMSET */
  148.           r6 - 92;         /* check if datum point is above baseline */
  149.           if (le) goto ABOVE_BL; /* if true, it is above the baseline */
  150.           r5 = -r6;      /* middle counter for draw of bar pixels */
  151.           r4 = 0;        /* top counter for clearing of pixel over bar */
  152.           r5 = r5 + 196; /* middle counter for draw of bar pixels */
  153.           goto DRAW_COL; /* go draw the column of pixels */
  154.           r6 = r6 - 92;  /* bottom counter for clearing of pixel under bar */
  155.  
  156. ABOVE_BL: r4 = -r6;      /* top counter for clearing of pixel over bar */
  157.           r4 = r4 + 100; /* top counter for clearing of pixel over bar */
  158.           r5 = r6 + 4;   /* middle counter for draw of bar pixels */
  159.           r6 = 0;        /* bottom counter for clearing of pixel under bar */
  160. DRAW_COL: *r13-- = r14;  /* save return address to the stack */
  161.           call r4+MEMSET (r14); /* zero the bytes above the bar */
  162.           r7 = r7 - r7;         /* force the register to zero */
  163.           call r5+MEMSET (r14); /* set the bytes of the bar */
  164.           r7 = r2;              /* MSB of byte is bar, others cleared */
  165.           call r6+MEMSET (r14); /* zero the bytes below the bar */
  166.           r7 = r7 - r7;         /* force the register to zero */
  167.           r13 = r13 + 2;        /* point to return address on the stack */
  168.           r14 = *r13;           /* load the return address from the stack */
  169. NO_BOT:   goto SHIFTBIT; /* go shift the bit pointer and clear up */
  170.           r3 = *r12;     /* reload the byte pointer */
  171.  
  172. ADD_BAR:  r6 = r6 * 2;   /* multiply offset by twelve to account for ... */
  173.           r6 = r6 * 2;   /* four bytes per instruction and ... */
  174.           r7 = r6 * 2;   /* three instructions per byte in MEM_OR */
  175.           r6 = r6 + r7;
  176.           r6 - 288;               /* check if datum below baseline */
  177.           if (gt) goto BELOW_BL; /* if true, datum is below baseline */
  178.           r6 = r6 - 288; /* calculate length of bar */
  179.           r6 = -r6;      /* datum above baseline length was negative */
  180.           r1 = -r1;      /* datum above baseline, increment is decrement */
  181. BELOW_BL: r6 = 288 - r6  /* align the counter for proper call */
  182.           r4 = r4 + r3;  /* add baseline offset to byte column pointer */
  183.           r5 = r4;
  184.           r5 = r5 + r1;  /* move pointer away from the baseline */
  185.           *r13-- = r14;  /* save return address to the stack */
  186.           r7 = 0;        /* zero initial storage value */
  187.           call r6+MEM_OR (r14);
  188.           r6 = r7;
  189.           r13 = r13 + 2;        /* point to return address on the stack */
  190.           r14 = *r13;           /* load the return address from the stack */
  191. #endif
  192.  
  193. SHIFTBIT: r2 = r2 >> 1;    /* shift the pixel pointed to right */
  194.           if (ne) goto NO_WRAP; /* if true, don't wrap the pixel pointer */
  195.           r12e = r12 - 2;  /* point to bit pointer storage */
  196.           r2 = 0x0080;     /* new bit mask if pixel wraps */
  197.           r3e = r3 + 1;    /* increment base to next byte upon wrap */
  198. NO_WRAP:  *r12++ = r2;     /* save the next bit pointer */
  199.           return (r14);
  200.           *r12++ = r3e;    /* save the next byte pointer start value */
  201.         /* END OF DRAWIMAG */
  202.  
  203. #if DSP32
  204.         /*  MEMSET -- set column of image bytes to a given value
  205.             registers used: r1 r3 r7 r14
  206.             input: r1 - postincrement value
  207.                    r3 - byte column pointer
  208.                    r7 - storage value
  209.                    r14 - return stack register, i.e. "TOP OF STACK"
  210.         */
  211. MEMSET:   *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;
  212.           *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;
  213.           *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;
  214.           *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;
  215.           *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;
  216.           *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;  *r3++r1 = r7l;
  217.           *r3++r1 = r7l;
  218.  
  219.           return (r14);
  220.           nop;
  221.         /* END OF MEMSET */
  222.  
  223.         /*  MEM_OR -- logical OR column of image bytes with a given value
  224.             registers used: r1 r4 r5 r6 r7 r14
  225.             input: r1 - postincrement value
  226.                    r2 - 'OR' value
  227.                    r4 - lagging byte column pointer
  228.                    r5 - leading byte column pointer
  229.                    r14 - return stack register, i.e. "TOP OF STACK"
  230.         */
  231. MEM_OR:   r6l = *r5++r1;  /* load column byte */
  232.           *r4++r1 = r7l;  /* save initial 'dummy' value */
  233.           r6 = r6 | r2;   /* 'OR' column byte with byte value */
  234.           r7l = *r5++r1;  /* load the next column byte */
  235.           *r4++r1 = r6l;  /* save the new column byte value */
  236.           r7 = r7 | r2;   /* 'OR' the next column byte with the byte value */
  237.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  238.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  239.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  240.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  241.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  242.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  243.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  244.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  245.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  246.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  247.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  248.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  249.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  250.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  251.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  252.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  253.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  254.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  255.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  256.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  257.           r6l = *r5++r1;  *r4++r1 = r7l;  r6 = r6 | r2;
  258.           r7l = *r5++r1;  *r4++r1 = r6l;  r7 = r7 | r2;
  259.           r6l = *r5++r1;  *r4++r1 = r7l;
  260.           return (r14);
  261.           nop;
  262.         /* END OF MEMSET */
  263. #endif
  264.  
  265. [LISTING THREE]
  266.  
  267. #include "dsp_type.h"
  268. #if DSP32
  269. #include "dspregs.h"
  270. #endif
  271.  
  272. .extern DECOMP, DRAWIMAG
  273. .extern WAVEADRS, WAVELVLS, IMAGSHOW, LVLADDRS
  274. .extern SIG_DRAW, DRAW_CNT, H_FILTER, L_FILTER
  275. .extern RST_DATA, IM0_PTRS, IM1_PTRS, IMAGE_0
  276. .extern STACKEND, SIGNALIN, DATA_OUT
  277.  
  278.         /*  ANALYZER 
  279.             main control program for the wavelet analyzer
  280.             registers used: r1 r2 r3 r4 r5 r6 r8 r9
  281.                             r11 r12 r13 r14 r15 r16 r17
  282.             accumulators used: a0 a1 a2 a3
  283.         */
  284. .rsect ".bank0"
  285.           dauc = 0x0000;  /* initialize DAU formats */
  286.           r1e = WAVELVLS; /* point to jump address for wavelet filter size */
  287.           r2e = SIGNALIN; /* point to approximation data storage */
  288.           r3 = *r1++;     /* load number of levels in wavelet transform */
  289.           r4 = 8;         /* load number of unit intervals per image */
  290.           r1e = r1 + 2;   /* point to the unit interval count storage */
  291.           *r1++ = r4;     /* store the unit interval count value */
  292.           r4 = r4 - r4;   /* zero the register */
  293.           *r1++ = r4;     /* set active image flag storage to 0 (IMAGE 0) */
  294.           a3 = a3 - a3;   /* intial data value is zero */
  295. #if DSP32C
  296.           r3 = r3 - 1;    /* number of levels in wavelet transform - 1 */
  297.           do 8, r3;       /* repeat next nine instructions r5+1 times */
  298. #else
  299.           r3 = r3 - 2;    /* number of levels in wavelet transform - 2 */
  300. #endif
  301. INITAPPX: *r1++ = r2e;   /* store base address of each approximation level */
  302.           *r2++ = a3 = a3; /* zero storage for approximation level */
  303.           *r2++ = a3 = a3; /* r2 ends up pointing to first location .... */
  304.           *r2++ = a3 = a3; /* in the next approximation level */
  305.           *r2++ = a3 = a3;
  306.           *r2++ = a3 = a3;
  307.           *r2++ = a3 = a3;
  308. #if DSP32C
  309.           nop;
  310.           *r1++ = r2e;    /* store the next location */
  311.           ioc = 0x40987;  /* initialize the serial I/O to the codec */
  312.           r1e = RST_DATA; /* point to reset pointer initialization storage */
  313.           r2e = SIG_DRAW; /* point to signal drawing data sets */
  314.           r3 = 26;        /* integer pointer index, 4 bytes per pointer */
  315.           r2e = r2 + 22;  /* point to bit pointer storage */
  316.           do 3, 7;        /* perform next 4 instructions eight times */
  317.           r4e = *r1++;    /* load initial bit pointer */
  318.           r5e = *r1++;    /* load initial byte column pointer */
  319.           *r2++ = r4;     /* store initial bit pointer */
  320.           *r2++r3 = r5e;  /* store initial byte column pointer */
  321. #else
  322.           if (r3-- >=0) goto INITAPPX; /* repeat for all arrays */
  323.           *r1++ = r2e;   /* store the next location */
  324.           ioc = 0x0987;  /* initialize the serial I/O to the codec */
  325.           r1 = RST_DATA; /* point to reset pointer initialization storage */
  326.           r2 = SIG_DRAW; /* point to signal drawing data storage */
  327.           r3 = 26;       /* integer pointer index, 2 bytes per pointer */
  328.           r2 = r2 + 22;  /* point to bit pointer storage */
  329.           r4 = 6;        /* initialize loop counter for eight loops */
  330. INIT_PTR: r5 = *r1++;    /* load initial bit pointer */
  331.           r6 = *r1++;    /* load initial byte column pointer */
  332.           *r2++ = r5;    /* store initial bit pointer */
  333.           if (r4-- >=0) goto INIT_PTR; /* repeat for all pointers */
  334.           *r2++r3 = r6;  /* store initial byte column pointer */
  335. #endif
  336.           r12e = WAVEADRS; /* load pointer to filter jump address */
  337.           r13e = STACKEND; /* load pointer to top of stack memory */
  338.           r11e = *r12++;   /* load jump address for filter size */
  339.           r16e = *r12++;   /* load coefficient pointer wrap back index */
  340.           r17 = *r12++;    /* load number of levels */
  341.           r15 = *r12;      /* load image data space size / 4 */
  342.           r3e = IMAGE_0;   /* point to the detail level float output */
  343. #if DSP32C
  344.           r15 = r15 - 1;   /* number of data points minus one */
  345.           do 0, r15;       /* repeat next instruction r15+1 times */
  346.           *r3++ = a3 = a3; /* clear four bytes in IMAGE_0 array */
  347. #else
  348.           r15 = r15 - 2;   /* number of data points minus two */
  349. CLR_IMAG: if (r15-- >=0) goto CLR_IMAG; /* repeat until all image cleared */
  350.           *r3++ = a3 = a3; /* clear four bytes in IMAGE_0 array */
  351. #endif
  352.           goto ENTRY_PT;   /* jump to the entry point */
  353.           nop;
  354.  
  355. MAINLOOP: r8 = DATA_OUT;        /* point to output data array */
  356.           r12e = SIG_DRAW;      /* point to signal drawing data sets */
  357.           r9e = DRAW_CNT;       /* point to draw count array */
  358.           a0 = *r8++;           /* load first signal data point */
  359.           r9e = r9 + r15;       /* index into draw count array */
  360.           call DRAWIMAG (r14);  /* draw the first input sample point */
  361.           r9l = *r9;            /* load the draw loop counter */
  362.           r12e = SIG_DRAW;      /* point to signal drawing data sets */
  363. DRWLOOP1: if (ibf) goto SAMPL_IN; /* if true, next sample available */
  364.           nop;
  365.           a0 = *r8++;           /* load data point */
  366.           call DRAWIMAG (r14);  /* draw data point */
  367.           nop;
  368.           if (r9-- >= 0) goto DRWLOOP1; /* repeat for all levels of xfrm */
  369. #if DSP32C
  370.           nop;
  371. #else
  372.           r12 = r12 + 2;        /* point to data set for next level */
  373. #endif
  374. WAITIBF1: if (ibe) goto WAITIBF1; /* wait until next data sample arrives */
  375.           nop;
  376.           goto TEST_LVL;
  377. SAMPL_IN: a3 = float(ibuf);      /* load the new signal sample */
  378. DRWLOOP2: a0 = *r8++;            /* load data point */
  379.           call DRAWIMAG (r14);   /* draw data point */
  380.           nop;
  381.           if (r9-- >= 0) goto DRWLOOP2;
  382. #if DSP32C
  383.           nop;
  384. #else
  385.           r12 = r12 + 2;         /* point to data set for next level */
  386. #endif
  387. TEST_LVL: r15 - 0;               /* test for process of all levels */
  388.           if (ne) goto ENTRY_PT; /* if true, all levels have not been done */
  389.           r12e = IMAGSHOW;       /* point to the unit interval count down */
  390.           nop;
  391.           r3 = *r12++;           /* load the unit interval count down */
  392.           r4 = *r12--;           /* load the image draw flag */
  393.           r3 = r3 - 1;           /* decrement the unit interval count */
  394.           if (ne) goto ENTRY_PT; /* if true, not done with new data set */
  395.           *r12++ = r3;           /* save the new count */
  396.           r3 = 8;                /* reset count to eight unit intervals */
  397.           r12 = r12 - 2;         /* point to unit interval count storage */
  398.           *r12++ = r3;           /* save the reset count */
  399.           pir = r4;              /* interrupt host processor for new image */
  400.           r4 = r4;               /* tickle CAU flags for image set */
  401.           if (ne) goto IM0_NEXT; /* if true, set up for drawing on IMAGE 0 */
  402.           nop;
  403.           r4 = 1;                /* next image displayed is IMAGE 1 */
  404.           goto PNTRINIT;         /* go to image pointer initialization */
  405.           r2e = IM1_PTRS;        /* set up for drawing on IMAGE 1 */
  406.  
  407. IM0_NEXT: r4 = 0;          /* next image displayed is IMAGE 0 */
  408.           r2e = IM0_PTRS;  /* set up for drawing on IMAGE 0 */
  409. PNTRINIT: r1 = SIG_DRAW;   /* point to signal drawing data sets */
  410.           *r12++ = r4;     /* save the image draw flag */
  411.           r1e = r1 + 24;   /* point to byte column pointer storage */
  412. #if DSP32C
  413.           r15e = 28;       /* set up post increment value */
  414.           do 0, 7;         /* perform next instruction eight times */
  415.           a0 = (*r1++r15 = *r2++) + a0; /* moves four bytes at once! */
  416. #else
  417.           r3 = 28;         /* set up post increment value */
  418.           r4 = 6;          /* set up loop counter for eight iterations */
  419. REINIPTR: r5 = *r2++;      /* load image array pointer */
  420.           if (r4-- >= 0) goto REINIPTR; /* repeat for all pointers */
  421.           *r1++r3 = r5;    /* store image array pointer */
  422. #endif
  423. WAIT_PIE: if (pif) goto WAIT_PIE; /* wait for pif flag to be cleared */
  424.           nop;
  425. ENTRY_PT: r3e = SIGNALIN;           /* point to input signal storage array */
  426. WAITIBF2: if (ibe) goto WAITIBF2;   /* wait until next data sample arrives */
  427.           r15 = r17;                /* inititialize the recursion counter */
  428.           *r3++ = a2 = float(ibuf); /* output second data sample first */
  429.           r6e = DATA_OUT;    /* point to output data array */
  430.           *r3 = a3 = a3;     /* output first data sample last */
  431.           *r6++ = a3 = a3;   /* place first sample in data output array */
  432.           *r6++ = a2 = a2;   /* place second sample in data output array */
  433.           r1e = H_FILTER;    /* point to detail filter coefficients */
  434.           r2e = L_FILTER;    /* point to approx. filter coefficients */
  435.           r12e = LVLADDRS;   /* point to data level address pointers */
  436.           a0 = a0 - a0;      /* zero the accumulators */
  437.           call DECOMP (r14); /* start the recursive decomposition */
  438.           a1 = a0;
  439.           goto MAINLOOP;
  440.           nop;
  441.  
  442.  
  443. [LISTING FOUR]
  444.  
  445. /* WAVEDATA.S */
  446. #include "dsp_type.h"
  447. #if DSP32
  448. #include "dspregs.h"
  449. #endif
  450.  
  451. .global WAVEADRS, WAVELVLS, IMAGSHOW, LVLADDRS
  452. .global SIG_DRAW, DRAW_CNT, H_FILTER, L_FILTER
  453. .global RST_DATA, IM0_PTRS, IM1_PTRS, IMAGE_0
  454. .global STACKEND, SIGNalIN, DATA_OUT
  455.  
  456. .align 4
  457. WAVEADRS: int24 0;       /* jump address for wavelet filter length */
  458. WAVEINDX: int24 0;       /* wrap back index for wavelet filter length */
  459. WAVELVLS: int   6, 1625; /* number of levels, clear loop counter */
  460. IMAGSHOW: int   8, 0;    /* unit interval count, active image pointer */
  461. LVLADDRS: int24 SIGNalIN, APPROX_5; /* data pointer storage for level 5 */
  462.  
  463.           int24 APPROX_5, APPROX_4; /* data pointer storage for level 4 */
  464.           int24 APPROX_4, APPROX_3; /* data pointer storage for level 3 */
  465.           int24 APPROX_3, APPROX_2; /* data pointer storage for level 2 */
  466.           int24 APPROX_2, APPROX_1; /* data pointer storage for level 1 */
  467.           int24 APPROX_1, 0;        /* data pointer storage for level 0 */
  468. .align 4
  469. SIG_DRAW: float 0.0, 24.0, 48.0, 0.0; /* scaling and offset coefficients */
  470.           int   0, 64;                /* temp storage, row increment */
  471.           int   1536, 0;              /* baseline value, bit pointer */
  472.           int24 0;                    /* byte column pointer */
  473. .align 4
  474.           float 0.0, 24.0, 48.0, 0.0;
  475.           int   0, 32;
  476.           int   768, 0;
  477.           int24 0;
  478. .align 4
  479.           float 0.0, 24.0, 48.0, 0.0;
  480.           int   0, 16;
  481.           int   384, 0;
  482.           int24 0;
  483. .align 4
  484.           float 0.0, 24.0, 48.0, 0.0;
  485.           int   0, 8;
  486.           int   192, 0;
  487.           int24 0;
  488. .align 4
  489.           float 0.0, 24.0, 48.0, 0.0;
  490.           int   0, 4;
  491.           int   96, 0;
  492.           int24 0;
  493. .align 4
  494.           float 0.0, 24.0, 48.0, 0.0;
  495.           int   0, 2;
  496.           int   48, 0;
  497.           int24 0;
  498. .align 4
  499.           float 0.0, 24.0, 48.0, 0.0;
  500.           int   0, 2;
  501.           int   48, 0;
  502.           int24 0;
  503. .align 4
  504.           float 0.0, 24.0, 48.0, 0.0;
  505.           int   0, 2;
  506.           int   48, 0;
  507.           int24 0;
  508.  
  509. DRAW_CNT: byte 6, 4, 3, 2, 1, 0;
  510.  
  511. .align 4
  512. H_FILTER: 6*float 0.0; /* highpass wavelet filter storage allocation */
  513. L_FILTER: 6*float 0.0; /* lowpass wavelet filter storage allocation */
  514.  
  515. /* image pointer reset initialization data */
  516. RST_DATA: int24 0x02; /* position of first pixel in unit interval at reset */
  517.           int24 IM0INITS; /* 00 00 00 00 00 00 00 01 */
  518.  
  519.           int24 0x01, IM0INIT5; /* 00 00 00 01 */
  520.  
  521.           int24 0x01, IM0INIT4; /* 00 01 */
  522.  
  523.           int24 0x01, IM0_LVL3; /* 01 */
  524.  
  525.           int24 0x10, IM0_LVL2; /* 10 */
  526.  
  527.           int24 0x40, IM0_LVL1; /* 40 */
  528.  
  529.           int24 0x80, IM0_LVL0; /* 80 */
  530.  
  531.           int24 0x80, IM0_LVLA; /* 80 */
  532.  
  533. /* image pointer switch initialization data */
  534. IM0_PTRS: int24 IM0SIGNL, IM0_LVL5, IM0_LVL4, IM0_LVL3;
  535.           int24 IM0_LVL2, IM0_LVL1, IM0_LVL0, IM0_LVLA;
  536. IM1_PTRS: int24 IM1SIGNL, IM1_LVL5, IM1_LVL4, IM1_LVL3;
  537.           int24 IM1_LVL2, IM1_LVL1, IM1_LVL0, IM1_LVLA;
  538.  
  539. /* IMAGE 0 storage allocation */
  540. IMAGE_0:
  541. IM0SIGNL: 7*byte 0;
  542. IM0INITS: 3193*byte 0;
  543.  
  544. IM0_LVL5: 3*byte 0;
  545. IM0INIT5: 1597*byte 0;
  546.  
  547. IM0_LVL4: byte 0;
  548. IM0INIT4: 799*byte 0;
  549.  
  550. IM0_LVL3: 400*byte 0;
  551.  
  552. IM0_LVL2: 200*byte 0;
  553.  
  554. IM0_LVL1: 100*byte 0;
  555.  
  556. IM0_LVL0: 100*byte 0;
  557.  
  558. IM0_LVLA: 100*byte 0;
  559.  
  560. /* IMAGE 1 storage allocation */
  561. IM1SIGNL: 3200*byte 0;
  562. IM1_LVL5: 1600*byte 0;
  563. IM1_LVL4: 800*byte 0;
  564. IM1_LVL3: 400*byte 0;
  565. IM1_LVL2: 200*byte 0;
  566. IM1_LVL1: 100*byte 0;
  567. IM1_LVL0: 100*byte 0;
  568. IM1_LVLA: 100*byte 0;
  569.  
  570. .align 2
  571. STACKBSE: 31*int24 0; /* subroutine stack storage allocation */
  572. STACKEND: int24 0;
  573.  
  574. .rsect ".hi_ram"
  575. SIGNalIN: 6*float 0.0; /* approximation data storage allocation */
  576. APPROX_5: 6*float 0.0;
  577. APPROX_4: 6*float 0.0;
  578. APPROX_3: 6*float 0.0;
  579. APPROX_2: 6*float 0.0;
  580. APPROX_1: 6*float 0.0;
  581. DATA_OUT: 9*float 0.0; /* output data storage allocation */
  582.  
  583.  
  584. [LISTING FIVE]
  585.  
  586. DSP_REGS.H
  587.  
  588. /* register file redefinition */
  589. #define  r1e   r1
  590. #define  r2e   r2
  591. #define  r3e   r3
  592. #define  r4e   r4
  593. #define  r5e   r5
  594. #define  r6e   r6
  595. #define  r7e   r7
  596. #define  r8e   r8
  597. #define  r9e   r9
  598. #define  r10e  r10
  599. #define  r11e  r11
  600. #define  r12e  r12
  601. #define  r13e  r13
  602. #define  r14e  r14
  603. #define  r15e  r15
  604. #define  r16e  r16
  605. #define  r17e  r17
  606. #define  r18e  r18
  607. #define  r19e  r19
  608. #define  r20e  r20
  609. #define  r21e  r21
  610.  
  611. /* integer and float redefinition */
  612. #define  int24  int
  613. #define  float24  float
  614.  
  615. DSP_TYPE.32
  616. #define DSP32 1
  617.  
  618. DSP_TYPE.32C
  619. #define DSP32C 1
  620.  
  621. MAKE32.BAT
  622. copy dsp_type.32 dsp_type.h
  623. d3make -M2 -N -l analyzer.s decomp.s drawimag.s wavedata.s -o anlyzr32.dsp
  624.  
  625. MAKE32C.BAT
  626. copy dsp_type.32c dsp_type.h
  627. d3make -M6 -Q -O -l analyzer.s decomp.s drawimag.s wavedata.s -o anlyz32c.dsp
  628.  
  629.  
  630. [LISTING SIX]
  631.  
  632. V592x480.h
  633. void Set592x480(void);
  634. void ShiftWaveTraces(unsigned int src, unsigned int dest);
  635. void GetDSPimage(unsigned int dest, unsigned int io_addr);
  636.  
  637. V592x480.c
  638. /* Mode set routine for VGA 592x480 16-color mode. Tested with Borland C 2.0 */
  639. #include <stdlib.h>
  640. #include <dos.h>
  641.  
  642. unsigned char palette_set[17]={0,64,60,3,4,5,6,55,1,62,1,62,56,62,7,62,0};
  643. void Set592x480(void)
  644. {
  645.   union REGS regset;
  646.   struct SREGS sregset;
  647.  
  648.   /* First, set to standard 640x480 mode (mode 12h) */
  649.   regset.x.ax = 0x0012;
  650.   int86(0x10, ®set, ®set);
  651.  
  652.   /* Next, set up the new color palette */
  653.   regset.x.ax = 0x1002;
  654.   regset.x.dx = (unsigned int) palette_set;
  655.   sregset.es = _DS;
  656.   int86x(0x10, ®set, ®set, &sregset);
  657.  
  658.   /* Now, tweak the registers needed to convert the horizontal character
  659.      count from 80 to 74 characters (640 to 592 pixels) per line */
  660.  outportb(0x3D4, 0x11);           /* allow access to CRTC registers 0 - 7 */
  661.   outportb(0x3D5, inportb(0x3D5) & 0x7f);
  662.   outport(0x3D4, 0x4901);        /* adjust the Horizontal Display Enable End
  663.                                  register for 74 byte display area width */
  664.   outport(0x3D4, 0x2513);        /* adjust the Offset register for 74 byte
  665.                                  (37 word) display area width */
  666.   /* adjust Line Compare register to start display of non-flipping area at 
  667.    line 400 (row scan number 399 (0x18f) */
  668.   outportb(0x3D4, 9);              /* clear tenth bit of Line Compare count */
  669.   outportb(0x3D5, inportb(0x3D5) & 0xbf);
  670.   outportb(0x3D4, 7);              /* set ninth bit of Line Compare count */
  671.   outportb(0x3D5, inportb(0x3D5) | 0x10);
  672.   outport(0x3D4, 0x8f18);         /* remaining eight bits of Line Compare */
  673.  
  674.   /* adjust the Start Address High and Start Address Low registers
  675.      to start screen display on page 0 */
  676.   outport(0x3D4, 0x170c);
  677.   outport(0x3D4, 0x200d);
  678.  
  679.   outportb(0x3D4, 0x11); /* block access to CRTC registers 0 - 7 */
  680.   outportb(0x3D5, inportb(0x3D5) | 0x80);
  681. }
  682. #define CLD        0xfc
  683. #define PUSH_DS    0x1e
  684. #define PUSH_CX    0x51
  685. #define POP_DS     0x1f
  686. #define POP_CX     0x59
  687. #define REP        0xf3
  688. #define MOVSB      0xa4
  689. #define STOSB      0xaa
  690. #define INSW       0x6d
  691. #define DEC_AX     0X48
  692. #define DEC_CX     0X49
  693. #define DEC_DX     0X4a
  694. #define INC_DX     0X42
  695. #define DEC_SI     0X4e
  696. #define JNE        0X75
  697. #define OUT_DX_AL  0xee
  698. #define USE_ES     0x26
  699. #define MOV_AL_DI  0x058a
  700. #define MOV_CX_AX  0xc88b
  701. #define MOV_CX_DX  0xca8b
  702. #define ADD_DI_BX  0xfb03
  703. #define ADD_SI_BX  0xf303
  704. #define ADD_SI_CX  0xf103
  705. #define SUB_SI_CX  0xf12b
  706.  
  707. unsigned char colorarray[74];
  708. unsigned char leftedges[8]={0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
  709. unsigned char rightedges[8]={0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
  710. static unsigned int shift_blocks[7][2] = { {42, 32}, {26, 48}, {18, 56},
  711.       {14, 60}, {12, 62}, {11, 63}, {11, 63}};
  712. void ShiftWaveTraces(unsigned int src, unsigned int dest)
  713. {
  714.   int i;
  715.   /* set the Mode Register Write Mode to 1 */
  716.   outportb(0x3ce, 5);
  717.   outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x01);
  718.   /* set the Map Mask Register to enable writes to pixel planes
  719.      0, 1, and 3 and disable writes to pixel plane 2 */
  720.   outport(0x3c4, 0x0b02);
  721.   _SI = src;
  722.   _DI = dest + 10;
  723.   _ES = 0xa000;
  724.   __emit__(CLD); /* assure that MOVSB increments SI and DI */
  725.   for (i = 0; i < 7; i++)
  726.   {
  727.     _DX = shift_blocks[i][1]; /* load the length of each line for block */
  728.     _BX = shift_blocks[i][0]; /* init middle loop for wrap value for block */
  729.  
  730.     __emit__(PUSH_DS);
  731.  
  732.     _DS = 0xa000;
  733.     _AX = 50;          /* init middle loop for number of lines in block */
  734.  
  735.     __emit__(ADD_SI_BX, MOV_CX_DX, REP, MOVSB);
  736.     __emit__(ADD_DI_BX, DEC_AX, JNE, 0xf5, POP_DS);
  737.    }
  738.   /* set the Mode Register Write Mode to 0 */
  739.   outportb(0x3ce, 5);
  740.   outportb(0x3cf, inportb(0x3cf) & 0xfc);
  741.   /* set the Map Mask Register to enable writes to all pixel planes */
  742.   outport(0x3c4, 0x0f02);
  743. }
  744. static unsigned int imag_blocks[6][2]={{10,32},{42,16},{58,8},
  745.                                                         {66,4},{70,2},{72,1}};
  746. void GetDSPimage(unsigned int dest, unsigned io_addr)
  747. {
  748.   int i;
  749.   /* Map Mask register - set pixel planes 1, 2, and 3 to "0",
  750.      pixel plane 0 to "1" */
  751.   outport(0x3c4, 0x0102);
  752.   _DX = io_addr;
  753.   _DI = dest;
  754.   _ES = 0xa000;
  755.   __emit__(CLD); /* assure that INSW increments DI */
  756.   for (i = 0; i < 6; i++)
  757.   {
  758.     /* point to fill element offset */
  759.     _AX = imag_blocks[i][1]; /* load the length of each line for block */
  760.     _BX = imag_blocks[i][0]; /* init middle loop for wrap value for block */
  761.     _SI = 50;       /* init middle loop for number of lines in image block */
  762.  
  763.     __emit__(ADD_DI_BX); /* wrap destination pointer to next row of display */
  764.     __emit__(MOV_CX_AX, REP, INSW, DEC_SI, JNE, 0xf7);
  765.   }
  766.   _DI += 1;                /* offset pointer by one */
  767.   _CX = imag_blocks[5][0]; /* init middle loop for wrap value for block */
  768.   _SI = 100;        /* init middle loop for number of lines in image block */
  769.   __emit__(ADD_DI_BX, INSW, DEC_SI, JNE, 0xfa);
  770.   /* Map Mask register - set pixel planes 0 - 3 to "1" */
  771.   outport(0x3c4, 0x0f02);
  772. }
  773.  
  774.